home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
satellit
/
vstsrc
/
rtd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-28
|
27KB
|
891 lines
/*
* %W% %E% %U% [EXTREL_1.2]
*
* VersaTrack orbit calculations are based on those that appear in Dr. Manfred
* Bester's sattrack program (the Unix(tm) versions 1 and 2).
*
* The data from which the maps where generated come from "xsat", an
* X-Windows program by David A. Curry (N9MSW).
*
* Site coordinates come from various sources, including a couple of
* World Almanacs, and also from both of the programs mentioned above.
*
* The following are authors' applicable copyright notices:
*
*
* Copyright (c) 1992, 1993, 1994 Manfred Bester. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice and the following three paragraphs appear in all
* copies.
*
* Permission to incorporate this software into commercial products may be
* obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,
* Berkeley, CA 94709, USA.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*
* Copyright 1992 by David A. Curry
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation. The
* author makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* David A. Curry, N9MSW
* Purdue University
* Engineering Computer Network
* 1285 Electrical Engineering Building
* West Lafayette, IN 47907
* davy@ecn.purdue.edu
*
* VersaTrack Copyright (c) 1993, 1994 Siamack Navabpour. All Rights Reserved.
*
* Permission is hereby granted to copy, modify and distribute VersaTrack
* in whole, or in part, for educational, non-profit and non-commercial use
* only, free of charge or obligation, and without agreement, provided that
* all copyrights and restrictions noted herein are observed and followed, and
* additionally, that this and all other copyright notices listed herein
* appear unaltered in all copies and in all derived work.
*
* This notice shall not in any way void or superceed any of the other authors
* rights or privilages.
*
* VersaTrack IS PRESENTED FREE AND "AS IS", WITHOUT ANY WARRANTY OR SUPPORT.
* YOU USE IT AT YOUR OWN RISK. The author(s) shall not be liable for any
* direct, indirect, incidental, or consequential damage, loss of profits or
* other tangible or intangible losses or benefits, arising out of or related
* to its use. VersaTrack carries no warranty, explicit or implied, including
* but not limited to those of merchantability and fitness for a particular
* purpose.
*
* Siamack Navabpour, 12342 Hunter's Chase Dr. Apt. 2114, Austin, TX 78729.
* sia@bga.com or sia@realtime.com.
*/
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "resource.h"
#include "vstdefs.h"
#include "vsttype.h"
#include "vstextrn.h"
static short itemid[] = {
IDC_RTD_TIME, IDC_RTD_AZIMUTH,
IDC_RTD_ELEVATION, IDC_RTD_RANGE,
IDC_RTD_DOPPLER, IDC_RTD_PATHLOSS,
IDC_RTD_LATITUDE, IDC_RTD_LONGITUDE,
IDC_RTD_HEIGHT, IDC_RTD_VISIBILITY,
IDC_RTD_PHASE, IDC_RTD_SQUINT,
IDC_RTD_TMODE
};
#undef NITEMS
#define NITEMS (sizeof(itemid) / sizeof(itemid[0]))
void
convcoord(lat, lon, x, y)
double lat, lon;
int *x,*y;
{
lon = -lon - mapdata.m_minx;
lat = -lat - mapdata.m_miny;
*x = (int) (lon * ScaleX);
*y = (int) (lat * ScaleY) + ytop;
}
void
rtd_update(sp)
select_t *sp;
{
track_t *tp;
result_t *rp;
int x, y;
int inview;
char *itemp;
double ttime;
if (!sp)
return;
tp = sp->sl_tp;
rp = sp->sl_rp;
if (sp->flags & SE_RTD_SIM) {
sp->simtime += tp->steptime;
ttime = sp->simtime;
}
else
ttime = utctime();
rtd_lock(sp);
if (predict(modelflag, sp, ttime) == 0) {
rtd_unlock(sp);
rtd_finish(sp);
return;
}
convcoord(rp->r_lat, rp->r_long, &x, &y);
sp->satx = x;
sp->saty = y;
if (sp->first) {
sp->dsatx = sp->satx;
sp->dsaty = sp->saty;
}
if (!sp->rtdhwnd || (sp->flags & SE_RTD_SIM)) {
rtd_unlock(sp);
return;
}
rtd_unlock(sp);
itemp = sp->sl_itemp;
inview = rp->r_elevation > tp->minelevation;
rp->r_viswarn = 0;
timeStr(rp->r_time, tp->sitep, sp->flags, 0, itemp+(0*20));
sprintf(itemp+( 1*20), "%-3.1lf", rp->r_azimuth);
sprintf(itemp+( 2*20), "%-+2.1lf", rp->r_elevation);
sprintf(itemp+( 3*20), "%-.1lf", (sp->flags & SE_RTD_KM) ? rp->r_range :
rp->r_range / 1.6);
sprintf(itemp+( 4*20), "%-05d", (int)(rp->r_doppler+0.5));
sprintf(itemp+( 5*20), "%-.1lf", rp->r_pathloss);
sprintf(itemp+( 6*20), "%-.1lf %c", fabs(rp->r_lat), (rp->r_lat > 0) ? 'N' : 'S');
sprintf(itemp+( 7*20), "%-.1lf %c", fabs(rp->r_long), (rp->r_long > 0) ? 'W' : 'E');
sprintf(itemp+( 8*20), "%-.1lf", (sp->flags & SE_RTD_KM ) ?
rp->r_height : rp->r_height / 1.6);
itemp[9*20] = rp->r_insun;
itemp[9*20+1] = 0;
sprintf(itemp+(10*20), "%03d", rp->r_phase);
if (tp->satp->s_flags & SF_ATTITUDE)
sprintf(itemp+(11*20), "%.1lf", rp->r_squint);
else
strcpy(itemp+(11*20), "N/A");
sprintf(itemp+(12*20),"%-3.3s",rp->r_modestr);
strcpy (itemp+13*20, inview ? "Visible" : " ");
if (sp->first) {
sprintf(itemp+(14*20), "%-.31s, %-.39s", tp->sitep->c_name,
tp->sitep->c_locale );
itemp[14*20 - 1] = 0;
strncpy(itemp+(16*20), tp->satp->s_name, 19);
}
PostMessage(sp->rtdhwnd, RTD_UPDATE, (WPARAM) 0, (LPARAM) sp);
}
int
rtd_start(hwnd, hinst, sp)
HWND hwnd;
HANDLE hinst;
select_t *sp;
{
int rtd_task_id, error;
extern DWORD rtd_display_thread(select_t *);
extern char *ErrorString(int);
track_t *tp;
double ttime;
if (!sp)
return TRUE;
rtd_lock(sp);
if (sp->rtdhwnd || sp->running || sp->terminate) {
rtd_unlock(sp);
#ifdef _DEBUG_
diag("rtd still active: hwnd %x run %d term %d thhandle %x\n",
sp->rtdhwnd, sp->running, sp->terminate, sp->rtd_thread_handle);
#endif /* _DEBUG_ */
return TRUE;
}
tp = sp->sl_tp;
if (!tp->sitep || !tp->satp) {
rtd_unlock(sp);
return TRUE;
}
ttime = utctime();
if (sp->flags & SE_RTD_SIM) {
if (tp->starttime != -1.0)
sp->simtime = ttime = tp->starttime;
else
sp->simtime = ttime;
}
predict_init(modelflag, sp, ttime);
sp->first = 1;
sp->timerid = 0;
sp->timeron = 0;
sp->ticks = 0;
sp->flags &= ~(SE_THSTOP | SE_THSTOPPED);
sp->rtdhwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_RTD), Gwnd, RTDisplayProc);
error = GetLastError();
if ((sp->rtdhwnd == NULL) || (sp->rtdhwnd == INVALID_HANDLE_VALUE)) {
sp->rtdhwnd = NULL;
rtd_unlock(sp);
sprintf(tmpbuf,"cannot create rtd dlg window: %s",
ErrorString(error));
usermsg(tmpbuf);
return FALSE;
}
SetWindowLong(sp->rtdhwnd, DWL_USER, (LONG) sp);
SetClassLong(sp->rtdhwnd, GCL_HICON,
(long) LoadIcon(hinst, MAKEINTRESOURCE(IDI_RTDICON)));
sp->rtd_thread_handle = CreateThread(NULL, 0,
(PTHREAD_START_ROUTINE) rtd_display_thread, (LPVOID) sp,
CREATE_SUSPENDED, &rtd_task_id);
error = GetLastError();
if ((sp->rtd_thread_handle == NULL) ||
(sp->rtd_thread_handle == INVALID_HANDLE_VALUE)) {
sp->rtd_thread_handle = NULL;
DestroyWindow(sp->rtdhwnd);
rtd_unlock(sp);
sprintf(tmpbuf, "Cannot create display thread for satellite: %s",
ErrorString(error));
usermsg(tmpbuf);
return FALSE;
}
rtd_unlock(sp);
ResumeThread(sp->rtd_thread_handle);
return TRUE;
}
BOOL
rtd_finish(sp)
select_t *sp;
{
BOOL r = FALSE;
if (!sp)
return r;
rtd_lock(sp);
if (sp->running) {
sp->terminate = 1;
r = TRUE;
}
if (sp->rtdhwnd) {
rtd_unlock(sp);
DestroyWindow(sp->rtdhwnd);
r = TRUE;
}
else
rtd_unlock(sp);
return r;
}
BOOL CALLBACK RTDisplayProc(hwnd, message, wParam, lParam)
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
int i, iconic;
POINT *p;
select_t *sp;
char *itemp;
sp = (select_t *) GetWindowLong(hwnd, DWL_USER);
switch (message) {
case WM_INITDIALOG:
p = DialogPos(Gwnd, hwnd);
EnableWindow(hwnd, TRUE);
SetWindowPos(hwnd, 0, (int)p->x, (int)p->y, 0, 0,
SWP_NOZORDER | SWP_NOSIZE);
return TRUE;
case RTD_UPDATE:
sp = (select_t *) lParam;
ASSERT(sp);
itemp = sp->sl_itemp;
iconic = IsIconic(hwnd);
if (i = sp->first) {
sp->first = 0;
SetWindowText(hwnd, itemp+(16*20));
if (sp->flags & SE_RTD_UTC)
SendDlgItemMessage(hwnd, IDC_RTD0, WM_SETTEXT, (WPARAM)0,
(LPARAM) "Time ");
else if (sp->flags & SE_RTD_SLT)
SendDlgItemMessage(hwnd, IDC_RTD0, WM_SETTEXT, (WPARAM)0,
(LPARAM) "Site Time");
SendDlgItemMessage(hwnd, IDC_RTD_OBSERVED,
(UINT)WM_SETTEXT, (WPARAM) 0, (LPARAM) (itemp+(14*20)));
if (sp->flags & (SE_RTD_DIC|SE_RTD_HIC)) {
if (sp->flags & SE_RTD_HIC)
ShowWindow(hwnd, SW_HIDE);
ShowWindow(hwnd, SW_SHOWMINIMIZED);
iconic = TRUE;
}
else {
OpenIcon(hwnd);
ShowWindow(hwnd, SW_SHOW);
iconic = FALSE;
}
PostMessage(Gwnd, RTD_WRUNNING, (WPARAM)0, (LPARAM) hwnd);
}
if (!iconic || i)
for (i=0; i<NITEMS; i++)
SendDlgItemMessage(hwnd, itemid[i],
(UINT)WM_SETTEXT, (WPARAM)0, (LPARAM) (itemp+(i*20)));
if (itemp[13*20] != ' ') {
if (sp->timeron == (char)0) {
if ((sp->flags & (SE_RTD_BEEP|SE_RTD_SIM)) == SE_RTD_BEEP)
SendMessage(Gwnd, RTD_LONGBEEPUP, (WPARAM)0, (LPARAM) 0);
if ((sp->flags & SE_RTD_POA) && iconic) {
OpenIcon(hwnd);
if (sp->flags & SE_RTD_HIC)
ShowWindow(hwnd, SW_SHOW);
sp->flags |= SE_RTD_ICONIC; /* we opened it */
}
sp->ticks = 0;
i = 0;
iconic = (sp->sl_rp->r_rising) ? 613 : 890;
do {
sp->timerid = IDT_RTDBASE + sp->sl_index + i;
i++;
} while (!SetTimer(hwnd, (UINT) sp->timerid, (DWORD) iconic, (TIMERPROC)NULL));
sp->timeron = (char )1;
}
}
else {
if (sp->timeron) {
KillTimer(hwnd, sp->timerid);
sp->timeron = (char )0;
#ifdef BLINKICON
ShowWindow(hwnd, iconic ? SW_SHOWMINIMIZED : SW_SHOW);
#endif
SetWindowText(hwnd, itemp+(16*20));
SendDlgItemMessage(hwnd, IDC_RTD_INVIEW, WM_SETTEXT,
(WPARAM) 0, (LPARAM)" ");
if ((sp->flags & (SE_RTD_BEEP|SE_RTD_SIM)) == SE_RTD_BEEP)
SendMessage(Gwnd, RTD_LONGBEEPDOWN, (WPARAM)0, (LPARAM) 0);
if (!iconic && (sp->flags & SE_RTD_ICONIC)) {
if (sp->flags & (SE_RTD_DIC | SE_RTD_HIC)) {
if (sp->flags & SE_RTD_HIC)
ShowWindow(hwnd, SW_HIDE);
CloseWindow(hwnd);
}
}
sp->flags &= ~SE_RTD_ICONIC;
}
}
return TRUE;
case WM_SIZE:
if (!sp)
break;
if ((sp->flags & SE_STATE) && !IsIconic(hwnd)) {
if (sp->flags & SE_WNDISICON) {
if (sp->flags & SE_RTD_HIC)
ShowWindow(hwnd, SW_HIDE);
CloseWindow(hwnd);
}
else if (IsIconic(hwnd)) {
if (sp->flags & SE_RTD_HIC)
ShowWindow(hwnd, SW_SHOW);
OpenIcon(hwnd);
}
sp->flags &= ~SE_STATE;
return TRUE;
}
if (!IsIconic(hwnd) && sp)
rtd_update(sp);
else if (sp && (sp->flags & SE_RTD_HIC))
ShowWindow(hwnd, SW_HIDE);
break;
case WM_DESTROY:
if (InSendMessage())
ReplyMessage(TRUE);
if (sp->timeron) {
KillTimer(hwnd, sp->timerid);
sp->timeron = (char) 0;
}
SendMessage(Gwnd, (UINT) RTD_WINEXIT, (WPARAM) 0, (LPARAM) sp);
Sleep(0);
break;
case WM_TIMER:
itemp = sp->sl_itemp;
if (sp->timeron && LOWORD(wParam) == sp->timerid) {
sp->ticks++;
if (!IsIconic(hwnd)) {
SetWindowText(hwnd, itemp+(16*20));
SendDlgItemMessage(hwnd, IDC_RTD_INVIEW,
(UINT) WM_SETTEXT, (WPARAM) 0, (sp->ticks & 1) ?
(LPARAM) " " : (LPARAM) "Visible" );
}
else if ((sp->flags & (SE_RTD_BOA|SE_RTD_SIM)) == SE_RTD_BOA)
#ifdef BLINKICON
ShowWindow(hwnd, (sp->ticks & 1) ? SW_HIDE : SW_SHOWMINIMIZED);
#else
SetWindowText(hwnd, (sp->ticks & 1) ? itemp+(16*20) :
sp->sl_tp->sitep->c_name);
#endif
return TRUE;
}
break;
case WM_COMMAND:
if (InSendMessage())
ReplyMessage(TRUE);
if (LOWORD(wParam) == IDOK) {
if (sp->timeron) {
KillTimer(hwnd, sp->timerid);
sp->timeron = (char )0;
}
rtd_finish(sp);
return TRUE;
}
break;
case WM_CLOSE:
if (sp->timeron) {
KillTimer(hwnd, sp->timerid);
sp->timeron = (char )0;
}
break;
case RTD_TOGGLE_ICON:
ASSERT(sp);
if (IsIconic(hwnd)) {
OpenIcon(hwnd);
if (sp && (sp->flags & SE_RTD_HIC))
ShowWindow(hwnd, SW_SHOW);
rtd_update(sp);
}
else {
if (sp && (sp->flags & SE_RTD_HIC))
ShowWindow(hwnd, SW_HIDE);
CloseWindow(hwnd);
}
break;
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
ColorSet(wParam, CWHITE, 7); /* was 5=dark magenta, is 6=dark cyan */
return (BOOL) hDrawBrush[7]; /* text color was 8 = light grey */
case WM_CTLCOLOREDIT:
ColorSet(wParam, CBLACK, 8);
return (BOOL) hDrawBrush[8];
}
return FALSE;
}
static BOOL
rtd_wantstop(select_t *sp)
{
return sp->terminate != 0;
}
static void
DrawSat(x, y, name)
int x, y;
char *name;
{
RECT r;
SIZE sz;
#define CRADIUS 4
display_lock();
Ellipse(hCompatDC, x - CRADIUS, y - CRADIUS, x + CRADIUS, y + CRADIUS);
DrawTextStr(hCompatDC, x + 5, y - 9, SRCINVERT, TextColor, CBLACK, hArial, name, &sz);
r.left = x - CRADIUS - 1 ;
r.right = r.left + 14 + sz.cx;
r.top = y - 10;
r.bottom = r.top + MAX(14, sz.cy);
RedrawScreen(&r);
display_unlock();
}
static void setdx(select_t *sp) { sp->dsatx = sp->satx; }
static int getdx(select_t *sp) { return sp->dsatx; }
static int getx(select_t *sp) { return sp->satx; }
static void setdy(select_t *sp) { sp->dsaty = sp->saty; }
static int getdy(select_t *sp) { return sp->dsaty; }
static int gety(select_t *sp) { return sp->saty; }
/*
* The thread used to display a satellite on the map. For each and every
* satellite/site pair one of these is created. As long as we have memory
* and cpu juice, why not!
*
* It is essential to use locks when updating the display bitmap, otherwise
* all sorts of hell will break loose. Hence, all those lock() and unlock()'s.
*/
static DWORD
rtd_display_thread(sp)
register select_t *sp;
{
int count,ticks;
BOOL pflag;
track_t *tp;
satellite_t *satp;
int updatecount,rs;
ASSERT(!sp->running);
ASSERT(!sp->terminate);
rtd_lock(sp);
if (sp->running) {
rtd_unlock(sp);
ExitThread(0);
}
sp->running = 1;
sp->terminate = 0;
rtd_unlock(sp);
pflag = FALSE;
tp = sp->sl_tp;
satp = tp->satp;
sat_lock();
if (!(satp->s_flags & SF_DISP))
satp->s_flags |= SF_DISP;
else
satp = NULL;
sat_unlock();
if (sp->flags & SE_RTD_SIM) {
rs = 100;
updatecount = 1;
}
else {
rs = RTD_SLEEPTIME;
updatecount = (int) ((float) (sp->updatetime * 1000) / (float) rs + 0.5) ;
}
GdiSetBatchLimit(1);
Sleep(((rand() >> 3) & 15) << 4);
PostMessage(Gwnd, RTD_TRUNNING, (WPARAM)0, (LPARAM) sp);
Sleep(20);
for (count=updatecount, ticks=0; ; ticks++) {
if (++count >= updatecount) {
count = 0;
rtd_update(sp);
}
rtd_lock(sp);
if (rtd_wantstop(sp)) {
rtd_unlock(sp);
break;
}
/*
* the SE_THSTOP flag is set when the user wants to re-draw the
* map while the thread is running. We'll freeze (i.e., suspend the
* thread) until the map is re-drawn, and then resume in a fresh
* state pretending that we haven't drawn the satellite on the map
* yet.
*/
if (sp->flags & SE_THSTOP) {
sp->flags |= SE_THSTOPPED;
rtd_unlock(sp);
PostMessage(Gwnd, RTD_STOPPED, (WPARAM) 0, (LPARAM) sp);
SuspendThread(sp->rtd_thread_handle);
Sleep(0); /* give up time slice just in case suspend thread doesn't
take effect immediately. */
rtd_lock(sp);
sp->flags &= ~SE_THSTOPPED;
rtd_unlock(sp);
sp->first = 1;
rtd_update(sp);
pflag = FALSE; /* we did all that for this */
}
else
rtd_unlock(sp);
if (satp) {
if (sp->flags & SE_RTD_BMP) {
DrawSat(getdx(sp), getdy(sp), tp->satp->s_name);
pflag = !pflag;
}
else {
if (!pflag) {
DrawSat(getdx(sp), getdy(sp), tp->satp->s_name);
pflag = TRUE;
}
}
}
else
pflag = TRUE;
if (satp && pflag && ((getdx(sp) != getx(sp)) || (getdy(sp) != gety(sp)))) {
if (sp->flags & SE_RTD_BMP)
Sleep((DWORD)rs);
DrawSat(getdx(sp), getdy(sp), tp->satp->s_name);
rtd_lock(sp);
setdx(sp);
setdy(sp);
rtd_unlock(sp);
pflag = !pflag;
}
if (sp->flags & SE_RTD_BMP || pflag)
Sleep((DWORD)rs);
if (!satp && (ticks > 25)) {
ticks = 0;
satp = tp->satp;
sat_lock();
if (!(satp->s_flags & SF_DISP)) {
satp->s_flags |= SF_DISP;
pflag = FALSE;
}
else
satp = NULL;
sat_unlock();
}
}
ASSERT(sp->running);
ASSERT(sp->terminate);
Sleep(100);
if (satp && pflag) {
DrawSat(getdx(sp), getdy(sp), tp->satp->s_name);
}
if (satp) {
sat_lock();
satp->s_flags &= ~SF_DISP;
sat_unlock();
}
#ifdef _DEBUG_
if (sp->terminate)
diag("thread %x by cmd, window handle %x\n",
sp->rtd_thread_handle, sp->rtdhwnd);
#endif /* _DEBUG_ */
rtd_lock(sp);
#if 0
sp->running = 0;
sp->terminate = 0;
sp->rtd_thread_handle = NULL;
#endif
if (sp->rtdhwnd) {
rtd_unlock(sp);
DestroyWindow(sp->rtdhwnd);
}
else
rtd_unlock(sp);
Sleep(0);
PostMessage(Gwnd, RTD_THDEXIT, (WPARAM) 0, (LPARAM) sp);
Sleep(50);
ExitThread((DWORD) 0);
return 0;
}
BOOL
rtd_anythread()
{
select_t *sp;
int n;
for (n = 0, sp = selInfo; sp; sp = sp->sl_next) {
rtd_lock(sp);
if (sp->running || sp->terminate || sp->rtdhwnd)
n++;
rtd_unlock(sp);
}
return n ? TRUE : FALSE;
}
BOOL
rtd_allstopped()
{
select_t *sp;
int n;
for (n = 0, sp = selInfo; sp; sp = sp->sl_next) {
rtd_lock(sp);
if (sp->running && !(sp->flags & SE_THSTOPPED) && (sp->flags & SE_THSTOP))
n++;
rtd_unlock(sp);
}
return n ? FALSE : TRUE;
}
void
rtd_allstop()
{
select_t *sp;
for (sp = selInfo; sp; sp = sp->sl_next) {
rtd_lock(sp);
if (sp->running) {
if (!(sp->flags & SE_THSTOPPED) && !(sp->flags & SE_THSTOP) ) {
sp->flags &= ~SE_THSTOPPED;
sp->flags |= SE_THSTOP;
}
}
rtd_unlock(sp);
}
}
BOOL
rtd_allrunning()
{
select_t *sp;
int n;
for (n = 0, sp = selInfo; sp; sp = sp->sl_next) {
rtd_lock(sp);
if (sp->running && !sp->terminate && sp->rtdhwnd && !(sp->flags & SE_THSTOPPED)) {
rtd_unlock(sp);
continue;
}
rtd_unlock(sp);
return FALSE;
}
return TRUE;
}
void
rtd_allresume()
{
select_t *sp;
int i;
for (i=0,sp = selInfo; sp ; sp = sp->sl_next, i++) {
rtd_lock(sp);
if (sp->running && (sp->flags & SE_THSTOPPED)) {
rtd_unlock(sp);
ResumeThread(sp->rtd_thread_handle);
}
else
rtd_unlock(sp);
}
}
void
rtd_savewindowstate() /* called when the main window is being minimized */
{
select_t *sp;
int i;
for (i=0,sp = selInfo; sp ; sp = sp->sl_next, i++) {
rtd_lock(sp);
if (sp->running && sp->rtdhwnd)
sp->flags |= SE_STATE;
if (IsIconic(sp->rtdhwnd))
sp->flags |= SE_WNDISICON;
else
sp->flags &= ~SE_WNDISICON;
rtd_unlock(sp);
}
}
#ifdef _DEBUG_
void
thdump(flag)
int flag;
{
select_t * sp;
int i;
extern int debugflag;
debugflag = 1;
for (i=0, sp = selInfo; sp; sp = sp->sl_next,i++) {
diag("%02d R=%d T=%d T=%08x W=%08x F=%08x\n",
i, sp->running, sp->terminate, sp->rtd_thread_handle,
sp->rtdhwnd, sp->flags & (SE_THSTOP|SE_THSTOPPED));
}
debugflag = 0;
}
#endif /* _DEBUG_ */
select_t *
checksat(x, y) /* see if mouse cursor is near one of the satellites on the map*/
int x,y;
{
RECT r;
POINT p;
select_t *sp;
p.x = x;
p.y = y;
for (sp = selInfo; sp; sp = sp->sl_next) {
rtd_lock(sp);
if (sp->running && sp->rtdhwnd) {
r.left = sp->dsatx - 10;
r.right = sp->dsatx + 10;
r.top = sp->dsaty - 10;
r.bottom = sp->dsaty + 10;
rtd_unlock(sp);
if (PtInRect(&r, p)) {
if ((sp != currentSel) && ((serverInfo[0].srv_state == ST_SRV_RUNNING) ||
(serverInfo[1].srv_state == ST_SRV_RUNNING)))
if (!yesno("Radio/Rotator Control running. Are you sure you \
want to change the current satellite ?"))
return NULL;
return currentSel = sp;
}
}
else
rtd_unlock(sp);
}
return NULL;
}